﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using NutriStat.Data;

namespace NutriStat
{
    public partial class OpenTableDialog : OpenTableDialogBase
    {
        //protected FormMainMenu menu;
        //private string m_sConnectionString;        
        //private string m_sFileName;
        //protected NutriStat.Data.IDbDriver db;
        //protected DataTable dt;

        /// <summary>
        /// Constructor
        /// </summary>
        public OpenTableDialog() : base()
        {
            InitializeComponent();            
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="callingMenu">The form that opened this form</param>
        public OpenTableDialog(FormBase callingMenu) : base(callingMenu)
        {
            InitializeComponent(); 
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="callingMenu">The form that opened this form</param>
        /// <param name="database">The database to load</param>
        /// <param name="table">The table in the database</param>
        public OpenTableDialog(FormBase callingMenu, NutriStat.Data.IDbDriver database, DataTable table)
            : base(callingMenu, database, table)
        {
            InitializeComponent(); 
        }

        protected internal override void ConfigureFormControls()
        {
            base.ConfigureFormControls();
            
            textBoxTableName.Visible = false;
            labelTableName.Visible = false;
            this.Width = 348;
            this.Height = 410;

            this.buttonCancel.Location = new Point(buttonCancel.Location.X, 352);
            this.buttonOK.Location = new Point(buttonOK.Location.X, 352);
            this.buttonClear.Location = new Point(buttonClear.Location.X, 352);
            this.buttonHelp.Location = new Point(buttonHelp.Location.X, 352);            
        }

        /*
        public OpenTableDialog(FormMainMenu mainMenu)
        {
            InitializeComponent();
            menu = mainMenu;
            menu.UseWaitCursor = true;
            menu.Enabled = false;

            ConnectionString = "";

            db = new AccessDatabase();
            dt = new DataTable();
        }

        public OpenTableDialog(FormMainMenu mainMenu, NutriStat.Data.IDbDriver database, DataTable table)
        {
            InitializeComponent();
            menu = mainMenu;
            menu.UseWaitCursor = true;
            menu.Enabled = false;

            ConnectionString = menu.Patient.ConnectionString;
            maskedTextBoxDataSource.Text = ConnectionString;

            db = database;
            dt = table;

            PopulateTableNames();
        }

        ~OpenTableDialog()
        {
            menu.UseWaitCursor = false;
            menu.Enabled = true;
            db.Dispose();
            dt.Dispose();
        }
        */
        /*
        #region Properties
        /// <summary>
        /// Gets/sets the file name being used; only applicable for MS Access        
        /// </summary>
        public string FileName
        {
            get
            {
                return m_sFileName;
            }
            set
            {
                m_sFileName = value;
            }
        }

        /// <summary>
        /// Gets/sets the connection string 
        /// </summary>
        public string ConnectionString
        {
            get
            {
                return m_sConnectionString;
            }
            set 
            {
                m_sConnectionString = value;
            }
        }        
        #endregion
        */
        
        #region Event Handlers
        /*
        /// <summary>
        /// Handles the Click event for the Cancel button
        /// </summary>
        /// <param name="sender">Object that fired the event</param>
        /// <param name="e">.NET supplied event parameters</param>
        protected void buttonCancel_Click(object sender, EventArgs e)
        {
            menu.UseWaitCursor = false;
            menu.Enabled = true;
            db.Dispose();
            dt.Dispose();
            this.Close();
        }

        /// <summary>
        /// Handles the Load event for FormOpenTable
        /// </summary>
        /// <param name="sender">Object that fired the event</param>
        /// <param name="e">.NET supplied event parameters</param>
        private void FormOpenTable_Load(object sender, EventArgs e)
        {
            ConfigureFormControls();
        }

        /// <summary>
        /// Handles the Click event for the Data Source Browse button
        /// </summary>
        /// <param name="sender">Object that fired the event</param>
        /// <param name="e">.NET supplied event parameters</param>
        protected void buttonDataSourceBrowse_Click(object sender, EventArgs e)
        {            
            // If the user selected Access
            if (comboBoxDatabaseType.Text.Equals("Microsoft Access Database"))
            {
                listBoxTables.Items.Clear();

                DialogResult result = openFileDialogExistingTable.ShowDialog();

                if (result == DialogResult.Cancel)
                {
                    return;
                }

                FileName = openFileDialogExistingTable.FileName;
                if (FileName.Equals(string.Empty))
                {
                    return;
                }

                db = new AccessDatabase();
                db.ConnectionString = AccessDatabase.BuildConnectionString(FileName, null);

                menu.Patient.ConnectionString = FileName;
                maskedTextBoxDataSource.Text = FileName;

                PopulateTableNames();
            }

            // If the user selected SQL Server
            else if (comboBoxDatabaseType.Text.Equals("Microsoft SQL Server Database"))
            {
                // Show our SQL connection dialog
                SQLConnectDialog connectSQL = new SQLConnectDialog(this);
                connectSQL.Show();                
            }            
            // This must be re-set to the program's default, otherwise the program will be looking
            // for the reference MDBs inside the directory in which the file was just opened.
            Directory.SetCurrentDirectory(NutriConfig.GetCurrentDirectory());
        }

        /// <summary>
        /// Handles the Click event for the Clear button
        /// </summary>
        /// <param name="sender">Object that fired the event</param>
        /// <param name="e">.NET supplied event parameters</param>
        private void buttonClear_Click(object sender, EventArgs e)
        {
            maskedTextBoxDataSource.Text = string.Empty;
            listBoxTables.Items.Clear();
        }

        /// <summary>
        /// Handles the Click event for the OK button
        /// </summary>
        /// <param name="sender">Object that fired the event</param>
        /// <param name="e">.NET supplied event parameters</param>
        protected void buttonOK_Click(object sender, EventArgs e)
        {
            if (listBoxTables.SelectedItem == null)
                return;

            //DataTable dt = db.GetTableData(listBoxTables.SelectedItem.ToString());
            dt = db.GetTableData(listBoxTables.SelectedItem.ToString(), "*", "fldIdNo, fldCurrentDate ASC");
            dt.TableName = listBoxTables.SelectedItem.ToString();

            menu.Patient.Database = db;
            menu.Patient.Table = dt;
            menu.OpenDatabase();

            this.Close();
        }
        /// <summary>
        /// Handles the FormClosed event for this form
        /// </summary>
        /// <param name="sender">Object that fired the event</param>
        /// <param name="e">.NET supplied event parameters</param>
        protected void FormOpenTable_FormClosed(object sender, FormClosedEventArgs e)
        {
            menu.UseWaitCursor = false;
            menu.Enabled = true;
            // This must be re-set to the program's default, otherwise the program will be looking
            // for the reference MDBs inside the directory in which the file was just opened.
            Directory.SetCurrentDirectory(NutriConfig.GetCurrentDirectory());
        }
        */
        #endregion Event Handlers        

        #region Methods
        /*
        /// <summary>
        /// Checks if the given file name exists.
        /// </summary>
        /// <param name="value">Sets whether or not to check for the existence of the file.</param>
        protected void SetCheckFileExists(bool value)
        {
            openFileDialogExistingTable.CheckFileExists = value;
        }

        /// <summary>
        /// Gets whether or not to check for the existence of a file.
        /// </summary>
        /// <returns>bool</returns>
        protected bool GetCheckFileExists()
        {
            return openFileDialogExistingTable.CheckFileExists;
        }

        /// <summary>
        /// Begins the process for populating the list of table names when using a SQL Server database.
        /// </summary>        
        public void PopulateSQL()
        {
            db = new SqlDatabase();
            db.ConnectionString = ConnectionString;
            menu.Patient.ConnectionString = ConnectionString;
            maskedTextBoxDataSource.Text = ConnectionString;
            PopulateTableNames();
        }

        /// <summary>
        /// Begins the process for populating the list of table names when using a MySQL database.
        /// </summary>        
        /// <param name="server">The server from which to pull the database.</param>
        /// <param name="database">The database to open.</param>        
        /// <param name="username">The username to use.</param>
        /// <param name="password">The password.</param>       
        public void PopulateMySQL(string server, string database, string username, string password)
        {
            //db = new MySqlDatabase();
            //db.ConnectionString = ConnectionString;
            //menu.Patient.ConnectionString = ConnectionString;
            //maskedTextBoxDataSource.Text = ConnectionString;
            //PopulateTableNames();
        }

        /// <summary>
        /// Configures the form controls based on the user's preferences and regional settings.
        /// </summary>
        private void ConfigureFormControls()
        {
            this.Text = SharedStrings.OPEN_TABLE;
            labelDatabaseType.Text = SharedStrings.DATABASE_TYPE;
            labelDataSource.Text = SharedStrings.DATA_SOURCE;
            groupBoxDataSourceExplorer.Text = SharedStrings.DATA_SOURCE_EXPLORER;
            buttonCancel.Text = SharedStrings.CANCEL;
            buttonOK.Text = SharedStrings.OK;
            buttonClear.Text = SharedStrings.CLEAR;
            buttonHelp.Text = SharedStrings.HELP;
        }

        /// <summary>
        /// Populates the form's listBox with all the table names in the current database.
        /// </summary>
        protected void PopulateTableNames()
        {
            maskedTextBoxDataSource.Text = menu.Patient.ConnectionString;

            List<string> tableNames = db.GetTableNames();
            listBoxTables.Items.Clear();

            foreach (string name in tableNames)
            {                
                listBoxTables.Items.Add(name);
            }
        }
        /*
        protected void PopulateList(string type, string fileName)
        {
            if (type == "Access")
            {
                listBoxTables.Items.Clear();
                maskedTextBoxDataSource.Text = fileName;
                menu.Patient.ConnectionString = fileName;

                // If the file doesn't exist, we need to create it; note this will
                // only ever happen in our inhereted class, NewTableDialog, because
                // the dialog box in the parent class does not allow the selection
                // of MDB files that do not already exist. (The child class does,
                // however.)
                if (!CheckFileExists(fileName))
                {
                    // Show a dialog box and prompt the user if they want to create the file.
                    DialogResult result = MessageBox.Show(this, "The file you specified does not exist. Would you " +
                        "like to create it now?", "Create file", MessageBoxButtons.YesNo, 
                        MessageBoxIcon.Question);

                    // If they say yes, then create it!
                    if (result == DialogResult.Yes)
                    {
                        // We could use ADO controls to create a new Access database, but
                        // apparently we don't have access to those controls since this is
                        // .NET 2.0 (perhaps I am wrong? May need to be looked into).

                        // So instead we have come up with a different solution. We have
                        // included a blank Access 2007 database in our project called
                        // NutriBlank2007.accdb. When the user specifies an Access database
                        // file that does not already exist, we simply copy this file
                        // byte-for-byte to the path and name specified by the user.
                        //
                        // TODO: Need to test this with file extensions. What if the user
                        // types in "X"? Does it create X.accdb or just a file named X?
                        // We need to check for this, both when File Extensions are turned
                        // on in Windows and when they are turned off.
                        //
                        // Create our stream reader objects.
                        Stream stream = null;
                        FileStream fileStream = null;

                        // Try creating the file.
                        try
                        {
                            // Create our byte array
                            byte[] bArray;
                            System.Reflection.Assembly objAssembly = System.Reflection.Assembly.GetExecutingAssembly();

                            // Get the NutriBlank2007.accdb file, which is currently an embedded resource
                            // within the solution
                            stream = objAssembly.GetManifestResourceStream("NutriStat.NutriBlank2007.accdb");
                            // Make our array the size of the stream, which is now getting our blank Access database
                            bArray = new Byte[stream.Length];                            
                            stream.Read(bArray, 0, (int)stream.Length);
                            // Create the new file
                            fileStream = new FileStream(fileName, System.IO.FileMode.Create);
                            // Write the file out
                            fileStream.Write(bArray, 0, (int)stream.Length);
                            // Close the stream
                            fileStream.Close();
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                        finally
                        {
                            // Cleanup...
                            fileStream.Close();
                            fileStream = null;

                            stream = null;
                        }
                    }
                    // If they say no...
                    else
                    {
                        // Do nothing. They don't want to create the file, so
                        // we obviously want to skip trying to connect to it!
                        return;
                    }                    
                }

                db = new AccessDatabase();

                db.ConnectionString = AccessDatabase.BuildConnectionString(fileName, null);
                List<string> tNames = db.GetTableNames();

                foreach (string name in tNames)
                {
                    listBoxTables.Items.Add(name);
                }               
                
            }
            else if (type == "SQL Server")
            {                
                // Show our SQL connection dialog
                SQLConnectDialog connectSQL = new SQLConnectDialog(this);
                connectSQL.Show();
            }

            else if (type == "MySQL")
            {
                // Show our MySQL connection dialog
                MySQLConnectDialog connectMySQL = new MySQLConnectDialog(this);
                connectMySQL.Show();
            }
        }
        */
        /*
        private bool CheckFileExists(string fileName) {            
            return System.IO.File.Exists(fileName);
        }

        internal void ClearList()
        {
            listBoxTables.Items.Clear();
        }
         */
        #endregion Methods
        
    }
}
